package com.gpt.article.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import chatgpt.ChatGPT;
import chatgpt.entity.chat.ChatCompletion;
import chatgpt.entity.chat.ChatCompletionResponse;
import chatgpt.entity.chat.Message;
import com.gpt.article.domain.*;
import com.gpt.article.mapper.*;
import com.gpt.article.service.impl.taskHandle.GenTask;
import com.gpt.article.service.impl.taskHandle.task.XiGaoTasker;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.gpt.article.service.IGptSpiderArticleService;
import org.springframework.util.ObjectUtils;

/**
 * 采集文章Service业务层处理
 * 
 * @author zhuzi
 * @date 2023-10-24
 */
@Service
public class GptSpiderArticleServiceImpl implements IGptSpiderArticleService 
{
    @Autowired
    private GptSpiderArticleMapper gptSpiderArticleMapper;

    @Autowired
    private GptGenArticleTaskMapper gptGenArticleTaskMapper;

    @Autowired
    private  GptGenArticleTaskServiceImpl gptGenArticleTaskServiceImpl;

    @Autowired
    private GptSpiderArticleContentMapper gptSpiderArticleContentMapper;

    @Autowired
    private GptGenArticleMapper gptGenArticleMapper;
    @Autowired
    private GptGenArticleContentMapper gptGenArticleContentMapper;



    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 查询采集文章
     * 
     * @param id 采集文章主键
     * @return 采集文章
     */
    @Override
    public GptSpiderArticle selectGptSpiderArticleById(Long id)
    {
        return gptSpiderArticleMapper.selectGptSpiderArticleById(id);
    }

    /**
     * 查询采集文章列表
     * 
     * @param gptSpiderArticle 采集文章
     * @return 采集文章
     */
    @Override
    public List<GptSpiderArticle> selectGptSpiderArticleList(GptSpiderArticle gptSpiderArticle)
    {
        return gptSpiderArticleMapper.selectGptSpiderArticleList(gptSpiderArticle);
    }


    /**
     * 新增采集文章
     * 
     * @param gptSpiderArticle 采集文章
     * @return 结果
     */
    @Transactional
    @Override
    public Long insertGptSpiderArticle(GptSpiderArticle gptSpiderArticle)
    {
        System.out.println("设置时间："+DateUtils.getNowDate());
        gptSpiderArticle.setCreateTime(DateUtils.getNowDate());

        //插入
        if(StringUtils.isEmpty(gptSpiderArticle.getUrlMd5())){
            String md5pre = DateUtils.dateTimeNow()+"zhu" +gptSpiderArticle.getTitle();
            String md5 = Md5Utils.hash(md5pre);
            gptSpiderArticle.setUrlMd5(md5);
        }
        if(ObjectUtils.isEmpty(gptSpiderArticle.getPushTime())){
            gptSpiderArticle.setPushTime(DateUtils.getNowDate());
        }

        Long rows = gptSpiderArticleMapper.insertGptSpiderArticle(gptSpiderArticle);
        if(StringUtils.isNotNull(gptSpiderArticle.getArtContent())){
            insertGptSpiderArticleContent(gptSpiderArticle);
        }

        return rows;
    }

    /**
     * 修改采集文章
     * 
     * @param gptSpiderArticle 采集文章
     * @return 结果
     */
    @Transactional
    @Override
    public int updateGptSpiderArticle(GptSpiderArticle gptSpiderArticle)
    {
        gptSpiderArticle.setUpdateTime(DateUtils.getNowDate());
        String urlMd5[] = gptSpiderArticle.getUrlMd5().split(";");
        gptSpiderArticleMapper.deleteGptSpiderArticleContentByMd5s(urlMd5);
        insertGptSpiderArticleContent(gptSpiderArticle);
        return gptSpiderArticleMapper.updateGptSpiderArticle(gptSpiderArticle);
    }

    /**
     * 批量删除采集文章
     * 
     * @param ids 需要删除的采集文章主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteGptSpiderArticleByIds(Long[] ids)
    {
        gptSpiderArticleMapper.deleteGptSpiderArticleContentByIds(ids);
//        gptSpiderArticleMapper.deleteGptSpiderArticleContentByMd5(gptSpiderArticle.getUrlMd5());
        List<GptSpiderArticle> gptSpiderDiyList = gptSpiderArticleMapper.getSelectedArticles(ids);
        for(GptSpiderArticle gptSpiderArticle:gptSpiderDiyList){
            if(StringUtils.isNotNull(gptSpiderArticle.getUrlMd5())){
                gptSpiderArticleMapper.deleteGptSpiderArticleContentByMd5s(gptSpiderArticle.getUrlMd5().split(""));
            }
        }
        return gptSpiderArticleMapper.deleteGptSpiderArticleByIds(ids);
    }

    /**
     * 删除采集文章信息
     * 
     * @param id 采集文章主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteGptSpiderArticleById(Long id)
    {
        GptSpiderArticle gptSpiderArticle = gptSpiderArticleMapper.selectGptSpiderArticleById(id);
        gptSpiderArticleMapper.deleteGptSpiderArticleContentByMd5s(gptSpiderArticle.getUrlMd5().split(""));
        return gptSpiderArticleMapper.deleteGptSpiderArticleById(id);
    }

    @Override
    public List<GptSpiderDiy> getSpiderDiy() {
        return gptSpiderArticleMapper.getSpiderDiyBystatus();
    }



    @Override
    public Boolean deleteAllSource(){

        //1.0 删除历史已经存储，但是有可能发生了异常的数据
        Map<String, Object> params = new HashMap<String, Object>();
        String[] tableList = {"gpt_gen_article_content", "gpt_gen_article", "gpt_spider_article", "gpt_spider_article_content", "gpt_spider_article_title", "gpt_sys_file"};
        params.put("tableList", tableList);
//        params.put("govFrameId", govHandlerStep2VO.getGovPriceFrame().getId());
        gptSpiderArticleMapper.deleteAll(params);

//        gptSpiderArticleMapper.deleteAll();
        File file  = new File(RuoYiConfig.getUploadPath());
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }



    /**
     * 新增采集文章内容信息
     * 
     * @param gptSpiderArticle 采集文章对象
     */
    public void insertGptSpiderArticleContent(GptSpiderArticle gptSpiderArticle)
    {
        String urlMd5 = gptSpiderArticle.getUrlMd5();
        String artContent = gptSpiderArticle.getArtContent();
        GptSpiderArticleContent gptSpiderArticleContent =new GptSpiderArticleContent();
        gptSpiderArticleContent.setUrlMd5(urlMd5);
        gptSpiderArticleContent.setArtContent(artContent);
        gptSpiderArticleContentMapper.insertGptSpiderArticleContent(gptSpiderArticleContent);
//        List<GptSpiderArticleContent> gptSpiderArticleContentList = gptSpiderArticle.getGptSpiderArticleContentList();
//        Long id = gptSpiderArticle.getId();
//        if (StringUtils.isNotNull(gptSpiderArticleContentList))
//        {
//            List<GptSpiderArticleContent> list = new ArrayList<GptSpiderArticleContent>();
//            for (GptSpiderArticleContent gptSpiderArticleContent : gptSpiderArticleContentList)
//            {
//                gptSpiderArticleContent.setId(id);
//                list.add(gptSpiderArticleContent);
//            }
//            if (list.size() > 0)
//            {
//                gptSpiderArticleMapper.batchGptSpiderArticleContent(list);
//            }
//        }
    }


    @Override
    public Boolean toGenArticleByGpt(Map<String,Object> map){
        Integer oneToNum = Integer.valueOf(String.valueOf(map.get("oneToNum")));
        Integer txtlength =  Integer.valueOf(String.valueOf(map.get("txtlength")));

        //创建洗稿任务
        GptGenArticleTask genArticleTask = new  GptGenArticleTask();
        genArticleTask.setProce(0);
        genArticleTask.setArticleNum(oneToNum);
        genArticleTask.setStatus("1");
        genArticleTask.setSuccessNum(0);
        genArticleTask.setErrorNum(0);
        genArticleTask.setCreateTime(DateUtils.getNowDate());
        Long taskId = gptGenArticleTaskMapper.insertGptGenArticleTask(genArticleTask);

        String prompts = String.valueOf(map.get("genStyle"));
        Integer classId = Integer.valueOf(String.valueOf(map.get("classId")));
        String className = String.valueOf(map.get("className"));
        String useModel = String.valueOf(map.get("useModel"));


        if(StringUtils.isEmpty(prompts)){
                XiGaoTasker.upTask(taskId,1,1,1,"3");
                logger.error("生成文章提示词为空！");
                return false;
        }
//        Message message = Message.of(prompts);

        Message system = Message.ofSystem("你是一个拥有多种风格经验丰富的自媒体写手。" +
                "你是一个能够生成不同类型文章的AI助手。" );
//        Message ast = Message.ofAssistant("从");
//        标题输出按照<title>爆款标题内容</title>格式
        String extendPrompts =  "请你从<"+className+">的领域，帮我根据关键词<"+prompts+">以及搜集网络信息，" +
                "发挥充分的想象生成一篇文章，不能和网上的以及之前生成的重复,文章不能低于" +txtlength+"个汉字"+
                "生成的文章有以下要求，标题的字数要求在30个汉字以内：" +
                "1、拟1个新的爆款创意标题，标题输出按照<title>爆款标题内容</title>格式；" +
                "2、全文要求分成多个自然段，每个自然段字数控制均匀一些；" +
                "3、文章开篇，先对整篇文章做简单概括，生成一个100字左右的文章摘要，摘要要统领整篇文章，做出精彩的描述；" +
                "4、详细阐述的内容，每个自然段使用<p></p>包裹。" +
                "5、演示例子：<title>爆款标题</title>\n" +
                "<p>摘要内容</p>\n" +
                "<p>文字阐述内容</p>\n" +
                "<p>文字阐述内容</p>\n" +
                "<p>文字阐述内容</p>\n" ;

        Message user = Message.of(extendPrompts);


        logger.info("正在生成文章。。。");
        long startTime = System.currentTimeMillis();
        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model(useModel)
//                .model(ChatCompletion.Model.GPT_3_5_TURBO_16K.getName())
                .messages(Arrays.asList(system,user))
                .maxTokens(10000)
                .temperature(0.9)
                .build();
        logger.info("正在生成文章...");
        ChatGPT chatGPT;
        chatGPT = ChatGPT.builder()
                .apiKey(RuoYiConfig.getApiKeys())
                .timeout(900)
//                .proxy(proxy)
                .apiHost(RuoYiConfig.getGptApiHost()) //代理地址
                .build()
                .init();

        for(int i=0;i<oneToNum;i++){
            ChatCompletionResponse response = chatGPT.chatCompletion(chatCompletion);
            Message res = response.getChoices().get(0).getMessage();
            String genContent = res.getContent();
            String reg = "(?<=<title>).*?(?=</title>)";
            String newtitle = getNewTitle(reg,genContent);
            genContent = genContent.replaceAll("<title>"+newtitle+"</title>","");
            String mkey = DateUtils.dateTimeNow()+"zhu";
            String urlMd5 = Md5Utils.hash(mkey);

            GptSpiderArticleContent gptSpiderArticleContent =new  GptSpiderArticleContent();
            gptSpiderArticleContent.setUrlMd5(urlMd5);
            gptSpiderArticleContent.setArtContent(genContent);
            long contenid = gptSpiderArticleContentMapper.insertGptSpiderArticleContent(gptSpiderArticleContent);

            GptSpiderArticle gptSpiderArticle = new GptSpiderArticle();
            gptSpiderArticle.setTitle(newtitle);
//        gptSpiderArticle.setPromptsId(diy.getPromptsId());
//        gptSpiderArticle.setSpiderDiyId(diy.getId());
//        gptSpiderArticle.setSpiderDiyName(diy.getName());
            gptSpiderArticle.setContentId(contenid);
            gptSpiderArticle.setUrlMd5(urlMd5);
            gptSpiderArticle.setClassId(classId);
            gptSpiderArticle.setClassName(className);
            gptSpiderArticle.setSourceId(3l);
            gptSpiderArticle.setSourceName("本平台");
            gptSpiderArticle.setStatus("0");
            gptSpiderArticle.setPushTime(DateUtils.getNowDate());
            gptSpiderArticle.setStatus("1");
//        gptSpiderArticle.setSpiderUrl(pageUrl);
            Long fileId = 0l;
            try {
                fileId = gptSpiderArticleMapper.insertGptSpiderArticle(gptSpiderArticle);
            }catch (Exception e){
                System.out.println("文章已存在无需保存："+e.getMessage());
            }



            GptGenArticleContent gptGenArticleContent =new  GptGenArticleContent();
            gptGenArticleContent.setUrlMd5(urlMd5);
            gptGenArticleContent.setArtContent(genContent);
            long gencontenid = gptGenArticleContentMapper.insertGptGenArticleContent(gptGenArticleContent);

            GptGenArticle genArticle = new GptGenArticle();
            genArticle.setTitle(newtitle);
            genArticle.setContentId(gencontenid);
            genArticle.setUrlMd5(urlMd5);
            genArticle.setStatus("0");
            genArticle.setGenArticleId(fileId);
            genArticle.setGenArticleTitle(newtitle);
            gptGenArticleMapper.insertGptGenArticle(genArticle);
//        upTask(taskId,xn,0,percentage,"1");
            XiGaoTasker.upTask(taskId,1,0,1,"2");

        }

        return true;
    }


    public  String getNewTitle(String reg, String content){
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(content);
        String regString = "";
        if( matcher.find() ){
            System.out.println(matcher.group());
            regString = matcher.group();
        }
        return regString;
    }




    /**
     * 洗稿文章
     *
     * @param
     */
    @Override
    public int toStartXigaoAll(GptSpiderArticle gptSpiderArticle, Map<String,Object> map) {
        System.out.println(gptSpiderArticle.toString());
        List<GptSpiderArticle> articles = gptSpiderArticleMapper.selectGptSpiderArticleList(gptSpiderArticle);
        setProcessArt(articles);
        Integer oneToNum = Integer.valueOf(String.valueOf(map.get("oneToNum")));
        Integer txtlength = Integer.valueOf(String.valueOf(map.get("txtlength")));
        Boolean tuswitch = Boolean.valueOf(String.valueOf(map.get("tuswitch")));
        Boolean xituSwitch = Boolean.valueOf(String.valueOf(map.get("xituSwitch")));

        int genNum = oneToNum*articles.size();
        //        articles.forEach(art -> art.getTitle());
          //代理
//            Proxy proxy = Proxys.http("127.0.0.1", 1080);
        GptGenArticleTask genArticleTask = new  GptGenArticleTask();
        genArticleTask.setProce(0);
        genArticleTask.setArticleNum(genNum);
        genArticleTask.setStatus("1");
        Long taskId = gptGenArticleTaskMapper.insertGptGenArticleTask(genArticleTask);
        //洗稿任务
        Integer xigaoAllNum = new GenTask().createXigao(articles,taskId,map);
        return xigaoAllNum;
    }

    /**
     * 文章洗稿中状态
     * @param gptSpiderDiyList
     * @return
     */
    public Boolean setProcessArt(List<GptSpiderArticle> gptSpiderDiyList){
        for(GptSpiderArticle li:gptSpiderDiyList){
            if(!"2".equals(li.getStatus())){
                li.setStatus("2");
                gptSpiderArticleMapper.updateGptSpiderArticle(li);
            }
        }
        return true;
    }
    /**
     * 文章洗稿失败状态
     * @param gptSpiderDiyList
     * @return
     */
    public Boolean seFailArtStatus(List<GptSpiderArticle> gptSpiderDiyList){
        for(GptSpiderArticle li:gptSpiderDiyList){
            if(!"2".equals(li.getStatus())){
                li.setStatus("2");
                gptSpiderArticleMapper.updateGptSpiderArticle(li);
            }
        }
        return true;
    }


    /**
     * 洗稿文章
     *
     * @param
     */
    @Override
    public Boolean startXigao(Long[] ids, Map<String,Object> map) {
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        WebSocketUsers.sendMessageToUsersByText(new XiGaoTasker().getMsgString("source",ids[0],0,"2"));
//
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        WebSocketUsers.sendMessageToUsersByText(new XiGaoTasker().getMsgString("source",ids[0],0,"3"));


        List<GptSpiderArticle> gptSpiderDiyList = gptSpiderArticleMapper.getSelectedArticles(ids);

        setProcessArt(gptSpiderDiyList);
        Integer oneToNum = Integer.valueOf(String.valueOf(map.get("oneToNum")));
        Integer txtlength = Integer.valueOf(String.valueOf(map.get("txtlength")));
        Boolean tuswitch = Boolean.valueOf(String.valueOf(map.get("tuswitch")));
        Boolean xituSwitch = Boolean.valueOf(String.valueOf(map.get("xituSwitch")));
        int genNum = oneToNum*gptSpiderDiyList.size();
        GptGenArticleTask genArticleTask = new  GptGenArticleTask();
        genArticleTask.setProce(0);
        genArticleTask.setArticleNum(genNum);
        genArticleTask.setStatus("1");
        genArticleTask.setSuccessNum(0);
        genArticleTask.setErrorNum(0);
        genArticleTask.setCreateTime(DateUtils.getNowDate());
        Long taskId = gptGenArticleTaskMapper.insertGptGenArticleTask(genArticleTask);

        //洗稿任务
        Integer xigaoAllNum = new GenTask().createXigao(gptSpiderDiyList,taskId,map);

        return true;
    }


//    public String checkArticle(List<GptSpiderArticle> gptSpiderDiyList){
////        new RunDataImpl().getGptSpiderArticle()
//    }

    public static void main(String[] args) {
        String path = "D:\\ruoyi\\uploadPath\\upload\\2023\\11\\21\\up_20231121151406A001\\美军“大规模演习23”将于8月9日至18日举行，为应对全球冲突做好准备.html";
        String contents = readHTMLFile(path);
        Document document = Jsoup.parse(contents);
        String cotent = document.text();
        System.out.println(cotent);
//        System.out.println(delHTMLTag(cotent));
    }

    public static String StripHT(String strHtml) {
        String txtcontent = strHtml.replaceAll("</?[^>]+>", ""); //剔出<html>的标签
        txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");//去除字符串中的空格,回车,换行符,制表符
        return txtcontent;
    }
    public static String readHTMLFile(String filePath) {
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content.toString();
    }
    /**
     * 去除html标签
     * @param htmlStr
     * @return
     */
    public static String delHTMLTag(String htmlStr){
        String regEx_script="<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
        String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
        String regEx_html="<[^>]+>"; //定义HTML标签的正则表达式

        Pattern p_script=Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);
        Matcher m_script=p_script.matcher(htmlStr);
        htmlStr=m_script.replaceAll(""); //过滤script标签

        Pattern p_style=Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
        Matcher m_style=p_style.matcher(htmlStr);
        htmlStr=m_style.replaceAll(""); //过滤style标签

        Pattern p_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
        Matcher m_html=p_html.matcher(htmlStr);
        htmlStr=m_html.replaceAll(""); //过滤html标签

        return htmlStr.trim(); //返回文本字符串
    }

}
